package com.ayoka.base;

import android.app.Activity;
import android.util.Log;

import com.ayoka.BuildConfig;
import com.ayoka.Constant;
import com.ayoka.R;
import com.ayoka.bean.UserInformation;
import com.ayoka.ui.launch.LaunchActivity;
import com.danikula.videocache.HttpProxyCacheServer;
import com.igexin.sdk.PushManager;
import com.igexin.sdk.PushService;
import com.jcp.baselibrary.base.APPActivityManager;
import com.jcp.baselibrary.base.AppCrashException;
import com.jcp.baselibrary.base.BaseApplication;
import com.jcp.baselibrary.model.ToolBarOptions;
import com.jcp.baselibrary.networkstate.NetInfo;
import com.jcp.baselibrary.networkstate.NetWorkEvent;
import com.jcp.baselibrary.networkstate.NetworkStateListener;
import com.jcp.baselibrary.networkstate.NetworkStateReceiver;
import com.jcp.baselibrary.okhttp3.OkHttpUtil;
import com.jincp.downloader.PRDownloader;
import com.jincp.downloader.PRDownloaderConfig;
import com.jincp.getui_push.DemoIntentService;
import com.jincp.image.compress.ImageCompressProxy;
import com.jincp.image.load.ImageLoaderOptions;
import com.jincp.image.load.ImageLoaderProxy;
import com.tencent.TIMGroupReceiveMessageOpt;
import com.tencent.TIMManager;
import com.tencent.TIMOfflinePushListener;
import com.tencent.TIMOfflinePushNotification;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.qalsdk.sdk.MsfSdkUtils;
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.timsdk.event.MessageEvent;
import com.tencent.timsdk.util.Foreground;
import com.tencent.tinker.lib.service.PatchResult;
import com.tencent.tinker.loader.app.ApplicationLike;
import com.tendcloud.tenddata.TCAgent;
import com.tinkerpatch.sdk.TinkerPatch;
import com.tinkerpatch.sdk.loader.TinkerPatchApplicationLike;
import com.tinkerpatch.sdk.tinker.callback.ResultCallBack;

import java.io.File;
import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;


/**
 * =========================================================
 * @ProjectName:
 * @ClassName: AppContext
 * @Description: Application基类
 * @Author: jincp
 * @CreateDate: 2019/3/14 13:44
 * =========================================================
 */
public class AppContext extends BaseApplication {

    public static HttpProxyCacheServer proxy;

    @Override
    public void onCreate() {
        super.onCreate();
        /**
         * tinker
         */
        initTinker();
        /**
         * Activity的管理
         */
        registerActivityLifecycleCallbacks(APPActivityManager.getInstance());
        /**
         * crash监听
         */
        AppCrashException.getInstance().init(this);
        CrashReport.initCrashReport(this, Constant.TENCENT_BUGLY_APPID, true);
        /**
         * OkHttp网络请求
         */
        initOkHttp3();
        /**
         * TalkingData
         */
        initTalkingData();
        /**
         * 腾讯云通信
         */
        initTIM();
        /**
         * 初始化X5内核
         */
        QbSdk.initX5Environment(this, null);
        /**
         * 初始化网络状态监听器
         */
        initNetworkStateListener();
        /**
         * 初始化图片加载
         */
        ImageLoaderProxy.getInstance().init(this);
        ImageLoaderOptions.init(0, R.mipmap.icon_image_load_error);
        /**
         * 初始化图片压缩
         */
        ImageCompressProxy.getInstance().init(this);
        /**
         * 初始化返回按钮图标
         */
        ToolBarOptions.setDefaultNavigateIconResource(R.mipmap.icon_back_black);
        /**
         * 初始化cache代理
         */
        initVideoProxy();
        /**
         * 初始化推送
         */
        initPush();
        /**
         * 初始化下载
         */
        initDownLoader();

    }

    /**
     * 初始化下载器
     */
    private void initDownLoader() {
        PRDownloaderConfig config = PRDownloaderConfig.newBuilder()
                .setDatabaseEnabled(true)
                .build();
        PRDownloader.initialize(this, config);
    }

    /**
     * 初始化推送消息
     */
    private void initPush() {
        PushManager.getInstance().initialize(this.getApplicationContext(), PushService.class);
        // DemoIntentService 为第三方自定义的推送服务事件接收类
        PushManager.getInstance().registerPushIntentService(this.getApplicationContext(), DemoIntentService.class);
    }

    /**
     * 初始化videoCache
     */
    private void initVideoProxy() {
        File cacheDirectory = new File(Constant.CourseVideoDirectory);
        if (!cacheDirectory.exists()) {
            cacheDirectory.mkdirs();
        }
        proxy = new HttpProxyCacheServer.Builder(this)
                .cacheDirectory(cacheDirectory)//缓存路径
                .maxCacheFilesCount(10)//最大缓存文件数量
                .maxCacheSize(100 * 1024 * 1024)//最大缓存大小
                .build();
    }
    /**
     * 初始化Tinker热修复
     */
     private void initTinker() {
        if (BuildConfig.TINKER_ENABLE) {
            // 我们可以从这里获得Tinker加载过程的信息
            ApplicationLike tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();

            // 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
            TinkerPatch.init(tinkerApplicationLike)
                    .reflectPatchLibrary()
                    //设置收到后台回退要求时,锁屏清除补丁,默认是等主进程重启时自动清除
                    .setPatchRollbackOnScreenOff(true)
                    //设置补丁合成成功后,锁屏重启程序,默认是等应用自然重启
                    .setPatchRestartOnSrceenOff(true)
                    .setPatchResultCallback(new ResultCallBack() {
                        @Override
                        public void onPatchResult(PatchResult patchResult) {
                            Log.e("TAG", "补丁修复:" + (patchResult.isSuccess ? "成功" : "失败"));
                        }
                    });

            //向后台获取是否有补丁包更新,默认的访问间隔为3个小时，若参数为true,即每次调用都会真正的访问后台配置
            //你也可以在用户登录或者APP启动等一些关键路径，使用fetchPatchUpdate(true)强制检查更新
            TinkerPatch.with().fetchPatchUpdate(true);
        }
    }

    /**
     * 初始化网络状态监听器
     */
    private void initNetworkStateListener() {
        NetworkStateListener networkStateListener = new NetworkStateListener() {
            @Override
            public void onNetworkState(boolean isNetworkAvailable, NetInfo netInfo) {
                NetWorkEvent.getInstance().onNetworkState(isNetworkAvailable, netInfo);
            }
        };
        //添加网络状态监听
        NetworkStateReceiver.addNetworkStateListener(networkStateListener);
    }


    /**
     * 初始化OkHttp3网络请求
     */
    private void initOkHttp3() {
        OkHttpClient.Builder builder = OkHttpUtil.getBuilder(true);
        // 设置token
        Interceptor mTokenInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request originalRequest = chain.request();
                if (UserInformation.getInstance() == null) {
                    return chain.proceed(originalRequest);
                }
                Request authorised = originalRequest.newBuilder()
                        .header("session_token", UserInformation.getInstance().session_token)
                        .build();
                return chain.proceed(authorised);
            }
        };
        builder.addInterceptor(mTokenInterceptor);
        OkHttpUtil.init(builder);
    }

    /**
     * 初始化TalkingData
     */
    private void initTalkingData() {
        TCAgent.init(this, "2F41CB55660140CFB46F0AAD3FB146D9", "com.ayoka");
        TCAgent.setReportUncaughtExceptions(true);
    }

    /**
     * 初始化TIMSDK
     */
    private void initTIM() {
        Foreground.init(this);
        if (MsfSdkUtils.isMainProcess(this)) {
            TIMManager.getInstance().init(getApplicationContext());
            TIMManager.getInstance().setOfflinePushListener(new TIMOfflinePushListener() {
                @Override
                public void handleNotification(TIMOfflinePushNotification notification) {
                    if (notification.getGroupReceiveMsgOpt() == TIMGroupReceiveMessageOpt.ReceiveAndNotify) {
                        //消息被设置为需要提醒
                        notification.doNotify(getApplicationContext(), R.mipmap.icon_ayoka_logo);
                    }
                }
            });
        }
    }

    /**
     * 登出
     * @param activity
     */
    public static void logout(Activity activity) {
        TIMManager.getInstance().logout(null);
        UserInformation.setUserInformation(null);
        MessageEvent.getInstance().clear();
        LaunchActivity.start(activity);
        activity.finish();
    }

}
